/* Filename: primer0_e.c
 * No.87.线程-线程竞争实例2
 * Description:
 * 多线程去计算某一范围内的质数
 * $ gcc -Wall primer0_e.c -o primer0_e -lpthread
 * Last modified: humble 2020-09-01 21:14:22
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>

#define LEFT (30000000)
#define RIGHT (30000200)
#define THRNUM (RIGHT - LEFT +1)

typedef struct{
    int n;
}thrarg_t;

static void *thr_primer(void *p);

int main(int argc, char **argv)
{
    int i,err;
    pthread_t tid[THRNUM];
    thrarg_t *p = NULL;
    void *ptr;

    for(i = LEFT; i <= RIGHT; i++)
    {
        p = malloc(sizeof(thrarg_t));
        if(!p){
            perror("malloc()");
            exit(1);
        }
        p->n = i;

        err = pthread_create(tid + (i - LEFT), NULL, thr_primer, p);
        if(err){
            //while(--i < 0){ pthread_join(tid[i - LEFT], NULL);free(.ptr.); } //未测
            fprintf(stderr, "pthread_create():%s\n", strerror(err));
            exit(1);
        }
    }

    for(i = LEFT; i <= RIGHT; i++){
        pthread_join(tid[i - LEFT], &ptr);
        free(ptr);
    }
    exit(0);
}

static void *thr_primer(void *p)
{
    int i, j, mark;
    i = ((thrarg_t *)p)->n;
    //free(p);
    mark = 1;
    for(j = 2; j < i/2; j++){
        if(i % j == 0){
            mark = 0;
            break;
        }
    }

    if(mark == 1){
        printf("%d is a primer\n", i);
    }
    pthread_exit(p); //把p返回给pthread_join
}
